#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
验证支付宝密钥配置是否正确
"""
import os
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from base64 import encodebytes

def verify_keys():
    """验证密钥配置"""
    base_dir = os.path.dirname(os.path.abspath(__file__))
    private_key_path = os.path.join(base_dir, 'keys', 'private.txt')
    public_key_path = os.path.join(base_dir, 'keys', 'public.txt')
    
    print("=" * 80)
    print("支付宝密钥验证工具")
    print("=" * 80)
    
    # 读取应用私钥
    try:
        with open(private_key_path, 'r', encoding='utf-8') as f:
            private_key_content = f.read().strip()
        print(f"[OK] 应用私钥文件读取成功: {private_key_path}")
        
        # 检查格式
        if not private_key_content.startswith('-----BEGIN'):
            print("[WARN] 警告: 应用私钥格式可能不正确（缺少PEM头部）")
        if not private_key_content.endswith('-----'):
            print("[WARN] 警告: 应用私钥格式可能不正确（缺少PEM尾部）")
            
        private_key = RSA.importKey(private_key_content)
        print(f"[OK] 应用私钥解析成功 (密钥长度: {private_key.size_in_bits()} bits)")
        
        # 从私钥生成公钥
        public_key_from_private = private_key.publickey()
        public_key_pem = public_key_from_private.export_key().decode('utf-8')
        print(f"[OK] 从应用私钥成功生成应用公钥")
        
    except FileNotFoundError:
        print(f"[ERROR] 错误: 应用私钥文件不存在: {private_key_path}")
        return False
    except Exception as e:
        print(f"[ERROR] 错误: 应用私钥解析失败: {str(e)}")
        return False
    
    # 读取支付宝公钥
    try:
        with open(public_key_path, 'r', encoding='utf-8') as f:
            alipay_public_key_content = f.read().strip()
        print(f"[OK] 支付宝公钥文件读取成功: {public_key_path}")
        
        alipay_public_key = RSA.importKey(alipay_public_key_content)
        print(f"[OK] 支付宝公钥解析成功 (密钥长度: {alipay_public_key.size_in_bits()} bits)")
        
    except FileNotFoundError:
        print(f"[ERROR] 错误: 支付宝公钥文件不存在: {public_key_path}")
        return False
    except Exception as e:
        print(f"[ERROR] 错误: 支付宝公钥解析失败: {str(e)}")
        return False
    
    # 测试签名和验证
    print("\n" + "-" * 80)
    print("测试签名功能...")
    print("-" * 80)
    
    try:
        # 创建测试数据
        test_data = b"test_signature_data_12345"
        
        # 使用应用私钥签名
        signer = PKCS1_v1_5.new(private_key)
        signature = signer.sign(SHA256.new(test_data))
        sign_base64 = encodebytes(signature).decode("utf8").replace("\n", "")
        print(f"[OK] 使用应用私钥签名成功")
        print(f"  签名值: {sign_base64[:50]}...")
        
        # 使用应用公钥验证签名（验证私钥和公钥是否匹配）
        verifier = PKCS1_v1_5.new(public_key_from_private)
        digest = SHA256.new(test_data)
        is_valid = verifier.verify(digest, signature)
        
        if is_valid:
            print(f"[OK] 应用私钥和应用公钥匹配验证成功")
        else:
            print(f"[ERROR] 错误: 应用私钥和应用公钥不匹配！")
            print(f"   请确保应用私钥和您在支付宝平台上传的应用公钥是配对的。")
            return False
            
    except Exception as e:
        print(f"[ERROR] 错误: 签名测试失败: {str(e)}")
        return False
    
    # 显示应用公钥（用于上传到支付宝平台）
    print("\n" + "-" * 80)
    print("应用公钥（请确保此公钥已上传到支付宝开放平台）:")
    print("-" * 80)
    print(public_key_pem)
    print("-" * 80)
    
    print("\n" + "=" * 80)
    print("[OK] 密钥验证完成！所有检查通过。")
    print("=" * 80)
    print("\n重要提示:")
    print("1. 请确保上面的应用公钥已经上传到支付宝开放平台")
    print("2. 支付宝平台会返回对应的支付宝公钥（已保存在 public.txt）")
    print("3. 如果仍然出现签名错误，请检查:")
    print("   - 应用公钥是否正确上传到支付宝平台")
    print("   - 支付宝公钥是否正确复制到 public.txt")
    print("   - 是否使用了正确的应用ID（APPID）")
    print("=" * 80)
    
    return True

if __name__ == '__main__':
    try:
        verify_keys()
    except KeyboardInterrupt:
        print("\n\n操作已取消")
    except Exception as e:
        print(f"\n[ERROR] 发生错误: {str(e)}")
        import traceback
        traceback.print_exc()

